<?php

require_once("EKElement.php");
require_once("EKUser.php");
require_once("EKEvaluation.php");
require_once("EKDocument.php");
require_once("EKParagraph.php");
require_once("EKTalk.php");
require_once("EKStatistics.php");

class EKRating extends EKElement{
	private $id;
	private $updateTime;
	private $enabled;
	private $ratingType;
	private $authorId;
	private $ownerId;
	private $ratingWeight;
	private $valueType;
	private $ratingValue;
	
	//Get the xml node by documentId
	static function getRatingXmlNode($id){
		$xmlfile = SERVERLOCATION."data/EKRating.xml";
		$doc = DOMDocument::load($xmlfile);
		$doc->validate();
		$node = $doc->getElementById($id);
		return $node;
	}
	
	//Rating Constructor
	function __construct($id){
		$this->id = $id;
		$node = EKRating::getRatingXmlNode($id);
		$this->enabled = $node->getAttribute("enabled");
		$this->ratingType = $node->getAttribute("ratingType");
		
		$this->authorId = $node->getElementsByTagName("authorId")->item(0)->nodeValue;
		$this->updateTime = $node->getElementsByTagName("updateTime")->item(0)->nodeValue;
		$this->ownerId = $node->getElementsByTagName("ownerId")->item(0)->nodeValue;
		$ratingValue = $node->getElementsByTagName("ratingValue")->item(0);
		$this->ratingValue = $node->getAttribute("value");
		$this->valueType = $node->getAttribute("type");
		$this->ratingWeight = $node->getAttribute("weight");
	}
	
	static function getWeightTypeValueById($id){
		$node = EKRating::getRatingXmlNode($id);
		$ratingValue = $node->getElementsByTagName("ratingValue")->item(0);
		$returnArray[] = $ratingValue->getAttribute("value");
		$returnArray[] = $ratingValue->getAttribute("type");
		$returnArray[] = $ratingValue->getAttribute("weight");
		return $returnArray;
	}
	
	static function getSameRating($ratingType, $authorId, $ownerId, $valueType)
	{
		$xmlfile = SERVERLOCATION."data/EKRating.xml";
		$doc = DOMDocument::load($xmlfile);
		$doc->validate();
		$root = $doc->getElementsByTagName("ratingRoot")->item(0);
		$i=0;
		$node = $root->getElementsByTagName("rating")->item($i);
		while($node)
		{
			if($ownerId == $node->getElementsByTagName("ownerId")->item(0)->nodeValue
			&& $authorId == $node->getElementsByTagName("authorId")->item(0)->nodeValue
			&& $ratingType == $node->getAttribute("ratingType")
			&& $valueType == $node->getElementsByTagName("ratingValue")->item(0)->getAttribute("type") )
			{
				return $node;
			}
			++$i;
			$node = $root->getElementsByTagName("rating")->item($i);
		}
		return false;
	}
	
	static function insertNewRating($ratingType, $ownerId, $valueType, $value)
	{
		$xmlfile = SERVERLOCATION."data/EKRating.xml";
		$doc = DOMDocument::load($xmlfile);
		$doc->validate();
		$root = $doc->getElementsByTagName("ratingRoot")->item(0);
		
		$node = $doc->createElement("rating");
    
    	$nodeId = EKStatistics::getRatingLastId();

    	$node->setAttribute("id", "_".$nodeId);
    	$node->setAttribute("enabled", "true");
   		$node->setAttribute("ratingType", $ratingType);

   		$authorId = $doc->createElement("authorId");
   		$authorIdText = $doc->createTextNode($_SESSION["userid"]);
   		$authorId->appendChild($authorIdText);
   
   		$ownerIdNode = $doc->createElement("ownerId");
   		$ownerIdNodeText = $doc->createTextNode($ownerId);
   		$ownerIdNode->appendChild($ownerIdNodeText);
   
   		$updateTime = $doc->createElement("updateTime");
   		$updateTimeText = $doc->createTextNode(time());
   		$updateTime->appendChild($updateTimeText);
   
   		$contentNode = $doc->createElement("ratingValue");
   		$contentNode->setAttribute("value", $value);
   		$contentNode->setAttribute("type", $valueType);
   		
   		$weight = EKEvaluation::lvToRatingWeight(EKUser::getAttributeById($_SESSION["userid"],"exp"));
   		$contentNode->setAttribute("weight", $weight);
   
	    $node->appendChild($authorId);
   		$node->appendChild($ownerIdNode);
   		$node->appendChild($updateTime);
   		$node->appendChild($contentNode);
   
   		$root->appendChild($node);

   		$doc->save($xmlfile);
   		
   		
   		// begin to update the owner
   		if($ratingType == "p")
   		{
   			$xmlfile = SERVERLOCATION."data/EKParagraph.xml";
   		}else if($ratingType == "d")
   		{
			$xmlfile = SERVERLOCATION."data/EKDocument.xml";
   		}else if($ratingType == "t")
   		{
   			$xmlfile = SERVERLOCATION."data/EKTalk.xml";
   		} else{
   			return;
   		}
   		$doc = DOMDocument::load($xmlfile);
   		$owner = $doc->getElementByID($ownerId);
   		$newIdNode =$doc->createElement("ratingId");
   		$newIdNodeText =$doc->createTextNode("_".$nodeId);
   		$newIdNode->appendChild($newIdNodeText);  
   		$preNode = $owner->getElementsByTagName("childId");
   		if($preNode)
   		{
   			$owner->insertBefore($newIdNode, $preNode->item(0));
   		}else{
   			$owner->appendChild($newIdNode);
   		}
   		$doc->save($xmlfile);
   		
   		return $nodeId;
   		// end of updating the owner
	}
	
	
	static function updateRating($type,$id){
	if($type == "p")
		{
	   		$xmlfile = SERVERLOCATION."data/EKParagraph.xml";
	   	}else if($type == "d")
	   	{
			$xmlfile = SERVERLOCATION."data/EKDocument.xml";
	   	}else if($type == "t")
	   	{
	   		$xmlfile = SERVERLOCATION."data/EKTalk.xml";
	   	}
	   	$doc = DOMDocument::load($xmlfile);
	   	$node = $doc->getElementByID($id);
	   	if($type == "d"){
	   		$userId = $node->getElementsByTagName("creatorId")->item(0)->nodeValue;
	   	} else {
	   		$userId = $node->getElementsByTagName("authorId")->item(0)->nodeValue;
	   	}
	   	
		$ratingIdSet = $node->getElementsByTagName("ratingId");
		$valueA = 0;
		$valueB = 0;
		$weightA = 0;
		$weightB = 0;
		foreach ($ratingIdSet as $ratingIdInstance) {
			$returnArray = EKRating::getWeightTypeValueById($ratingIdInstance->nodeValue);
			if("A" == $returnArray[1])
			{
	        	$valueA += $returnArray[0] * $returnArray[2];
	        	$weightA += $returnArray[2];
			}else{
	        	$valueB += $returnArray[0] * $returnArray[2];
	        	$weightB += $returnArray[2];
			}
		}
		if($weightA!=0){
			$valueA = $valueA/$weightA;
			$node->setAttribute("ratingAValue", $valueA);
			$node->setAttribute("ratingAWeight", $weightA);
		}
		if($weightB!=0){
			$valueB = $valueB/$weightB;
			$node->setAttribute("ratingBValue", $valueB);
			$node->setAttribute("ratingBWeight", $weightB);
		}
		
	   	$doc->save($xmlfile);
	   	EKRating::updateUserRating($userId);
	}
	
	static function updateUserRating($id){
		$thisUser = new EKUser($id);
		$thisDocIds = $thisUser->getDocumentCreatedIds();
		$thisParaIds = $thisUser->getParagraphCreatedIds();
		$thisTalkIds = $thisUser->getTalkCreatedIds();
		$valueA = 0;
		$valueB = 0;
		$weightA = 0;
		$weightB = 0;
		foreach($thisDocIds as $dId){
			if(EKDocument::testHaveRating($dId,"EKDocument")){
				$valueA += EKDocument::getRatingAValueById($dId) * EKDocument::getRatingAWeightById($dId) * EKEvaluation::$documentV;
				$weightA += EKDocument::getRatingAWeightById($dId) * EKEvaluation::$documentV;
				$valueB += EKDocument::getRatingBValueById($dId) * EKDocument::getRatingBWeightById($dId) * EKEvaluation::$documentV;
				$weightB += EKDocument::getRatingBWeightById($dId) * EKEvaluation::$documentV;
			}
		}
		foreach($thisParaIds as $pId){
			if(EKParagraph::testHaveRating($pId,"EKParagraph")){
				$valueA += EKParagraph::getRatingAValueById($pId) * EKParagraph::getRatingAWeightById($pId) * EKEvaluation::$paragraphV;
				$weightA += EKParagraph::getRatingAWeightById($pId) * EKEvaluation::$paragraphV;
				$valueB += EKParagraph::getRatingBValueById($pId) * EKParagraph::getRatingBWeightById($pId) * EKEvaluation::$paragraphV;
				$weightB += EKParagraph::getRatingBWeightById($pId) * EKEvaluation::$paragraphV;
			}
		}
		foreach($thisTalkIds as $tId){
			if(EKTalk::testHaveRating($tId,"EKTalk")){
				$valueA += EKTalk::getRatingAValueById($tId) * EKTalk::getRatingAWeightById($tId) * EKEvaluation::$talkV;
				$weightA += EKTalk::getRatingAWeightById($tId) * EKEvaluation::$talkV;
				$valueB += EKTalk::getRatingBValueById($tId) * EKTalk::getRatingBWeightById($tId) * EKEvaluation::$talkV;
				$weightB += EKTalk::getRatingBWeightById($tId) * EKEvaluation::$talkV;
			}
		}
		if($weightA!=0){
			$valueA = $valueA/$weightA;
			EKUser::updateDB($id,"ratingA",$valueA);
			EKUser::updateDB($id,"ratingAWeight",$weightA);
		}
		if($weightB!=0){
			$valueB = $valueB/$weightB;
			EKUser::updateDB($id,"ratingB",$valueB);
			EKUser::updateDB($id,"ratingBWeight",$weightB);
		}
	}
	
	# Delete current node
	static function deleteRatingNode($id){
		$xmlfile = SERVERLOCATION."data/EKRating.xml";
		$doc = DOMDocument::load($xmlfile);
		$doc->validate();
		$documentRoot = $doc->getElementsByTagName("ratingRoot")->item(0);
		$thisDoc = $doc->getElementById($id);		
		
		# this function is only called when the owner is deleted
		# so it does NOT delete reference of owner to it
		
		$r = new EKRating($id);

		$documentRoot->removeChild($thisDoc);
		EKStatistics::decRatingSumNum();
		EKUser::delRecord($r->authorId, "r", $id);
		$doc->save($xmlfile);
	}
}

?>